#!/usr/bin/env python
import sys
from liwe.module import LiweModule

class WebForm ( LiweModule ):
	def __init__ ( self, liwe ):
		super ( WebForm, self ).__init__ ( liwe, "webform" )
		self._tables = {	
			'main' : [ 'name', 'tpl', 'tpl_name', 'sender','subject' ],
			'form' : [ 'id', 'name', 'field', 'args', 'pos' ]
		}

	def add_field ( self, id_field = '', name = '', field = '', args = '', pos = '' ):
		# FIXME: args deve essere codificato in base64 e pos va risolto 
		if not name or not field or not args: 
			sys.stderr.write ( "WebForm::add_field parameters missing ( name: %s - field: %s - args: %s - pos: %s)\n" % ( name, field, args, pos ) )
			return 

		#SE POS E NULL LO RICAVO DAL PROSSIMO POS
		if not pos:
			pos = 1
			res = self.dbm.single_row ( "webform_form", "MAX(pos)+1 AS new_pos", "name = '%s'" % name )
			if  res:
	                        pos = res [ 'new_pos' ]
		
		id_field = self._insert ( "webform_form", id = id_field, name = name, field = field, args = args, pos = pos )
		return self.get_field ( id_field )
		

	def get_field ( self, id_field = 0 ):
		if not id_field : return []

		res = self.dbm.single_row ( "webform_form", self._tables [ 'form' ] , "id = '%s'" % id_field , safe = True )
			
		try:
			res [ 'args_dict' ] = eval ( res [ 'args' ] )
		except:
			pass
		return res


	def del_fields ( self, ids = '' ):
		if not ids :
			return
		ids = ids.split ( "|" )
		str_ids = " ,".join ( ids )

		self.dbm.delete ( "webform_form", " id IN ( %s ) " % str_ids )

        def list ( self, fname = '', start_point = 0, limit = 10 ):

		if not fname:
			return

		conds = " name = '%s' " % fname
                extras = " ORDER BY pos LIMIT %s,%s " % ( start_point, limit )

                tables = [ "webform_form" ]
                fields = [ "id", "name", "field", "args", "pos" ]

                tot_rows = self.dbm.count ( tables, fields )
		#self.dbm.debug = sys.stderr.write
                cur = self.dbm.select ( tables, fields, conds, extras = extras )
		#self.dbm.debug = None
                rows = []

                if cur:
                        for r in cur:
                                #self.list_manip ( r )
				r [ 'argstxt' ] = r [ 'args' ]
				try:
					r [ 'args' ] = eval ( r [ 'args' ] )
				except:
					pass
                                rows.append ( r )

                        cur.close ()

                return { "rows" : rows, "tot_rows" : tot_rows }

	def list_mails ( self, start_point = 0, limit = 0 ):
		extras = "ORDER BY id_destination LIMIT %s,%s " % ( start_point, limit )
		fields = [ "id_destination", "descr", "email" ]
			
                tot_rows = self.dbm.count ( "webform_destination", fields )
		rows = self.dbm.all_rows ( "webform_destination", fields ,  extras = extras  )
                
		if not rows:
			rows = []

                return { "rows" : rows, "tot_rows" : tot_rows }

	def set_destination ( self, mail_ids = '' , fname = '' ):
		
		if not fname:
			return

		if not mail_ids:
			self.dbm.delete ( "webform_rel", "name = '%s'" % fname ); 
			return

		ids = mail_ids.split ( "|" )

		if not ids:
			return

		self.dbm.delete ( "webform_rel", "name = '%s'" % fname ); 
		for id in ids:
			dct = { "name" : fname, "id_destination" : id }	
			self.dbm.insert ( "webform_rel", dct )

		return self.list_form_destinations ( fname )
		
	def clean_rel_table ( self, fname = '', optimize = '' ):
		# clean orphanes from webform_rel tables
		if optimize:
			res = self.dbm.all_rows ( "webform_form",  "name" , extras = "GROUP BY name" )
			if res:
				na = [ x [ 'name' ] for x in res ]
				form_names = "'" + "','".join ( na ) + "'"
				self.dbm.delete ( "webform_rel", "name NOT IN ( %s ) " % form_names )
		# delete by form name
		if not fname:
			return
		self.dbm.delete ( "webform_rel", "name = '%s'" % fname ); 

	def check_form_name ( self, name = '' ):
		res = self.dbm.single_row ( "webform_form" , "name" , "name = '%s'" % name ) 
		if not res :
			res = []
		return res 

	def edit_mail ( self, id_destination = '', descr = '', email = '' ):
		dct = { 'id_destination' : id_destination , 'descr' : descr, 'email' : email }
		
		if not id_destination:
			self.dbm.insert ( "webform_destination", dct )
			return
		
		self.dbm.update ( "webform_destination" , dct , "id_destination = %s " % id_destination )

	def del_mail ( self, ids ):
		if not ids :
			return
		ids = ids.split ( "|" )
		str_ids = " ,".join ( ids )

		self.dbm.delete ( "webform_destination" , "id_destination IN( %s )" % str_ids )

	def move_field ( self, start_id = '', move = '' ):
		if not start_id or ( move != 'up' and move != 'down' ) : return

		start_pos = self.dbm.single_row ( "webform_form", [ 'id', 'name', 'pos' ], "id = '%s'" % start_id ) 
		#sys.stderr.write ( "---- MOVE_FIELD :: start_pos [] id: %s - name: %s - pos: %s" % ( start_pos [ 'id' ], start_pos [ 'name' ], start_pos [ 'pos' ] ) )
		if not start_pos: return

		if move == 'down':
			conds = "pos > %s AND name = '%s'" % ( start_pos [ 'pos' ] , start_pos [ 'name' ] )
			extras = "ORDER BY pos ASC LIMIT 1"
		if move == 'up':
			conds = "pos < %s AND name = '%s'" % ( start_pos [ 'pos' ] , start_pos [ 'name' ] )
			extras = "ORDER BY pos DESC LIMIT 1"
		dest_pos = self.dbm.single_row ( "webform_form", [ 'id', 'name', 'pos' ], conds = conds , extras = extras ) 

		if not dest_pos : return
		#sys.stderr.write ( "---- MOVE_FIELD :: dest_pos [] id: %s - name: %s - pos: %s" % ( dest_pos [ 'id' ], dest_pos [ 'name' ], dest_pos [ 'pos' ] ) )
		self.dbm.update ( "webform_form", { 'pos' : dest_pos [ 'pos' ] }, "id = '%s'" % start_pos [ 'id' ] )
		self.dbm.update ( "webform_form", { 'pos' : start_pos [ 'pos' ] }, "id = '%s'" % dest_pos [ 'id' ] )

	# ---------------- PUBLIC FUNCTIONS ---------------- #

	def list_forms ( self ):

		conds = ''
		rows = self.dbm.all_rows ( "webform_form", "name" , conds , extras = " GROUP BY name ORDER BY name " )
		if not rows:
			rows = []
		return rows
	
 	def list_form_destinations ( self, fname = '' ):
		#self.dbm.debug = sys.stderr.write
		res =  self.dbm.all_rows ( "webform_rel" , "id_destination" , "name = '%s' " % fname )
		#self.dbm.debug = None

		mails = []
		if res:
			ids = []
			for r in res: 
				ids.append ( str ( r [ 'id_destination' ] ) )

			ids = ", ".join ( ids )
			
			mails = self.dbm.all_rows ( "webform_destination", [ "id_destination AS value", "descr AS label", "email" ],
						   " id_destination IN( %s )" % ids,  extras = " ORDER BY label" )

			if not mails: mails = []

		return mails
	

	def list_destinations ( self, id = '' ):

		fields = [ "id_destination AS value", "descr AS label" ]
		conds = ''
		order = 'ORDER BY label'
		if id:
			fields.append ( 'email' )
			conds = 'id_destination = %s ' % id
	
		#self.dbm.debug = sys.stderr.write
		return self.dbm.all_rows ( "webform_destination", fields , conds,  extras = order  )
		#self.dbm.debug = None

	def get_form_fields ( self, fname = '', id = '' ):
		if not fname and not id: 
			return []

		if id:
			fname = self.dbm.single_row ( "webform_form", "name", " id = %s " % id ) [ 'name' ]
			#sys.stderr.write ( "----- FORM NAME BY FIELD ID: %s" % fname )
		rows = self.dbm.all_rows ( "webform_form", [ "id", "name", "field", "args", "pos" ], " name = '%s' " % fname, extras = "ORDER BY pos" )
		if not rows:
			rows = []
		else:
			# aggiunge campi hidden con id form e form_name
			field = '{"name" : "wb_form_id","value" : "%(id)s"}' % rows [ 0 ]
			rows.append ( {'name': 'web_form_id', 'args': field , 'pos': '' , 'field': 'hidden' } )
			field = '{"name" : "wb_form_name","value" : "%(name)s"}' % rows [ 0 ]
			rows.append ( {'name': 'web_form_name', 'args': field , 'pos': '' , 'field': 'hidden' } )

		for row in rows:
			row [ 'argstxt' ] = row [ 'args' ]
			#sys.stderr.write ( "----- FORM NAME ROW: %s\n" % row )
			try:
				row [ 'args' ] = eval ( row [ 'args' ] )
			except:
				pass

		return rows


	def send_form ( self, form_vals ):
		wb_form_name = form_vals [ 'wb_form_name' ]


		sender_name = ''
		main_form = self.main_get ( name = wb_form_name )
		if main_form.get ( 'sender' ):
			sender_field =  self.get_field ( id_field = main_form [ 'sender' ] ) 
			sender_name =  sender_field [ 'args_dict' ] [ 'name' ]
	
		site_name = self.liwe.cfg.get ( "site.name", "Nome del sito" )
		subject = "Invio form da " + site_name
		if main_form.get( 'subject' ):
			subject = site_name + " : " + main_form [ 'subject' ]
			

		if not wb_form_name:
			return

		pop_vals = [ 'Invia', 'action', 'wb_form_id', 'wb_form_name' ]
		for rm in pop_vals:
			if form_vals.get ( rm ): 
				del form_vals [ rm ]


		form_txt = []
		form_html = [ '<html>','<body>', '<table border="0">' ]

		# Prendo i dati dalla tabella di destination
		tables = [ 'webform_destination as d', 'webform_rel as r' ]
		fields = [ 'd.descr', 'd.email as email']
		conds = [ 'd.id_destination = r.id_destination' ]
		conds.append ( "r.name = '%s'" % wb_form_name )
		#self.dbm.debug = sys.stderr.write 
		vals = self.dbm.all_rows ( tables , fields, " AND ".join ( conds ) )
		#self.dbm.debug = None 
		if not vals: return


		sender = self.cfg.get ( 'site.email.sender', 'noreply@example.com' )
		for form_field, value in form_vals.iteritems () :
			form_txt.append ( '%s : %s' % ( form_field, value ) )
			form_html.append ( '<tr><td align="right"><b>%s</b>:</td><td>%s</td></tr>' % ( form_field, value ) )
			if form_field == sender_name : sender = value

		form_html += [ '</table>', '</body>', '</html>' ]

		body_txt = "\n".join ( form_txt )
		body_html = "\n".join ( form_html )

		for email in [ str ( x [ 'email' ] ) for x in vals ]:
			m = self.liwe.email ( sender = sender, subject = subject )
			m.reply_to = form_vals.get ( "mail" )
			m.to ( email )
			m.text ( body_txt )
			m.html ( body_html )
			m.send ()

			#self.liwe.mail.send ( sender = self.cfg.get ( 'email.sender', 'noreply@example.com' ) , dest = email , subject = 'Invio form da ' + site_name , body = body_txt )


	#{{{MAIN
	def main_set ( self, name = '', tpl_name = '', sender = 0, subject = '' ):
		tpl = 0
		if tpl_name : tpl = 1
		return self._insert ( "webform_main", name = name, tpl = tpl, tpl_name = tpl_name, sender = sender, subject = subject )

	def main_update ( self, name = '', tpl = -1, tpl_name = '', sender = 0 ):
		if not name: return
		vals = { 'name' : name }
		if sender: vals [ 'sender' ] = sender
		if tpl <> -1 : vals [ 'tpl' ] = tpl
		if tpl_name : vals [ 'tpl_name' ] = tpl_name

		self.dbm.update ( "webform_main", vals, "name = '%s'" % name ) 
			
		return self.main_get ( name )
	

	def main_get ( self, name = '' ):
		if not name:  return []
		return self.dbm.single_row ( "webform_main", self._tables [ 'main' ] , "name = '%s'" % name , safe = True )
	
	def main_list ( self ):
		res = self.dbm.all_rows ( "webform_main" , self._tables [ 'main' ] )
		if not res : return []
		return res
			
	#}}}

	def _insert ( self, table_name, ** kwargs ):
		self.dbm.replace ( table_name, kwargs, debug = self.debug() )
		return self.dbm.insert_id ()

if __name__ == '__main__':
        from liwe import liwe
        from liwe.fake import FakePyHP
        import sys

        l = liwe ( pyhp = FakePyHP (), home_dir = 'work' )

        w = WebForm( l )

	"""
	print w.main_set ( name = 'contact' , tpl_name = "prova" );
	print w.main_get ( name = 'contact' );
	print w.main_set ( name = 'contact' );
	print w.main_get ( name = 'contact' );
	print w.main_list ();

	print w.main_set ( name = 'prova', tpl_name = 'ciccio' );
	print w.main_get ( name = 'prova' );
		
	print w.main_update ( name = 'prova', sender = 1 );
	print w.main_get ( name = 'prova' );


	"""


 
